package main

import (
	"fmt"
	"strconv"
)

func HumanBytesLoaded(bytesLength int64) string {
	var resp string
	//此处的定义变量感谢新疆的蔡徐坤同学，如此让下面的代码没有把我彻底疯掉
	var KB int64 = 1024
	var MB int64 = 1024 * 1024
	var GB int64 = 1024 * 1024 * 1024
	var TB int64 = 1024 * 1024 * 1024 * 1024
	var PB int64 = 1024 * 1024 * 1024 * 1024 * 1024
	var EB int64 = 1024 * 1024 * 1024 * 1024 * 1024 * 1024

	fmt.Printf("一脸懵逼的值：%d B\n", bytesLength)
	if bytesLength < KB {
		resp = strconv.FormatInt(bytesLength, 10) + "B"
	} else if bytesLength < MB {
		resp = strconv.FormatInt(bytesLength/KB, 10) + "KB," + strconv.FormatInt(bytesLength%KB, 10) + "B"
	} else if bytesLength < GB {
		resp = strconv.FormatInt(bytesLength/MB, 10) + "MB," + strconv.FormatInt(bytesLength%MB/KB, 10) + "KB," + strconv.FormatInt(bytesLength%MB%KB, 10) + "B"
	} else if bytesLength < TB {
		resp = strconv.FormatInt(bytesLength/GB, 10) + "GB," + strconv.FormatInt(bytesLength%GB/MB, 10) + "MB," + strconv.FormatInt(bytesLength%GB%MB/KB, 10) + "KB"
	} else if bytesLength < PB {
		resp = strconv.FormatInt(bytesLength/TB, 10) + "TB," + strconv.FormatInt(bytesLength%TB/GB, 10) + "GB," + strconv.FormatInt(bytesLength%TB%GB/MB, 10) + "MB"
	} else if bytesLength < EB {
		resp = strconv.FormatInt(bytesLength/PB, 10) + "PB," + strconv.FormatInt(bytesLength%PB/TB, 10) + "TB," + strconv.FormatInt(bytesLength%PB%TB/GB, 10) + "GB"
	} else {
		resp = strconv.FormatInt(bytesLength/EB, 10) + "EB" //实在是不想写了，感觉这样写好傻逼！
	}
	return resp
}

//于是有了下面这种方法:
func Human_Units_Conv(bytesLength int64) string {
	var resp string
	//此处的单位放在字符串中，以及下面的字符串粘贴，都感谢杭州的胡冀东同学，
	//让我最终用我自己的逻辑(一个不懂计算机底层二进制位移运算的高数逻辑)把问题解决。
	var units string = "BKMGTPEZYBND"

	fmt.Printf("一脸懵逼的值：%d B\n", bytesLength)
	if bytesLength < 1024 {
		resp = strconv.FormatInt(bytesLength, 10) + "B"
	} else {
		for _, v := range units {
			if bytesLength < 1024 {
				resp = strconv.FormatInt(bytesLength, 10) + string(v) + " " + resp
				break
			}
			resp = strconv.FormatInt(bytesLength%1024, 10) + string(v) + " " + resp
			bytesLength = bytesLength / 1024
		}
	}

	return resp
}
func main() {
	fmt.Println("一目了然的值:", HumanBytesLoaded(9223372036854775807)) //此数值是int64的最大值,二进制是:111111111111111111111111111111111111111111111111111111111111111
	fmt.Println("一目了然的值:", Human_Units_Conv(9223372036854775807))

	//两种方法的运行结果：
	// 一脸懵逼的值：9223372036854775807 B
	// 一目了然的值: 7EB
	// 一脸懵逼的值：9223372036854775807 B
	// 一目了然的值: 7E 1023P 1023T 1023G 1023M 1023K 1023B
	fmt.Println("您的时间银行余额：", Human_Time_Conv(1888888888)) //1,888,888,888秒 约=60年
	//运行结果：
	//您的时间银行余额： 60Y 8M 22D 3h 21m 28s (1888888888秒===60年8个月22天3小时21分钟28秒)
	//祝大家都能活到100岁:)
}

//扩展--年月日时分秒
func Human_Time_Conv(timeLength int64) string {
	var resp string
	var timeunits = "smhDMY" //倒序对应"年、月、日、时、分、秒"
	if timeLength < 60 {
		resp = strconv.FormatInt(timeLength, 10) + "s" //秒(s)在此程序为最小单位
		return resp                                    //后面没有语句，可以提前返回
	} else {

	LOOP:
		for i, v := range timeunits {
			switch i {
			case 0, 1:
				if timeLength < 60 {
					resp = strconv.FormatInt(timeLength, 10) + string(v) + " " + resp
					return resp //如果后面没有语句，return效率更高，直接返回结果，程序结束
				}
				resp = strconv.FormatInt(timeLength%60, 10) + string(v) + " " + resp
				timeLength = timeLength / 60
			case 2:
				if timeLength < 24 {
					resp = strconv.FormatInt(timeLength, 10) + string(v) + " " + resp
					break LOOP //如果后面还有语句，那就必须用标签定点结束
				}
				resp = strconv.FormatInt(timeLength%24, 10) + string(v) + " " + resp
				timeLength = timeLength / 24
			case 3:
				if timeLength < 30 {
					resp = strconv.FormatInt(timeLength, 10) + string(v) + " " + resp
					return resp
				}
				resp = strconv.FormatInt(timeLength%30, 10) + string(v) + " " + resp
				timeLength = timeLength / 30
			case 4:
				if timeLength < 12 {
					resp = strconv.FormatInt(timeLength, 10) + string(v) + " " + resp
					break LOOP
				}
				resp = strconv.FormatInt(timeLength%12, 10) + string(v) + " " + resp
				timeLength = timeLength / 12
			case 5:

				resp = strconv.FormatInt(timeLength, 10) + string(v) + " " + resp

			}
		}
	}
	return resp
}
